// Copyright (c) 2009 Luca Marrocco.
// Modified or written by Luca Marrocco for inclusion with codej.
// Licensed under the Apache License, Version 2.0 (the "License")
package codej.language.java;

import static codej.source.Languages.*;

import java.util.*;

import codej.ast.*;
import codej.ast.*;
import codej.parser.*;
import codej.parser.java.*;

/** @author Luca Marrocco */
public abstract class Recognize {

	private static boolean isClassBodyDeclaration(String source) {
		try {
			recognizeClassBodyDeclaration(source);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	private static boolean isFormalParameter(String source) {
		try {
			recognizeFormalParameter(source);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	private static boolean isInterfaceBodyDeclaration(String source) {
		try {
			recognizeInterfaceBodyDeclaration(source);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	private static boolean isLocalVariableDeclaration(String source) {
		try {
			Node node = recognizeLocalVariableDeclaration(source);
			return node instanceof LocalVariableDeclaration;
		} catch (Exception e) {
			return false;
		}
	}

	private static boolean isMethodBody(String source) {
		try {
			recognizeMethodBody(source);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public static final Node recognize(Object object) {
		String source = new ParserAgent(JavaParser.class).baseDir("src/test/java").read(object.getClass().getName());
		CompilationUnit compilationUnit = (CompilationUnit) compile(java(source));
		return compilationUnit;
	}

	public static final Node recognize(String source) {
		if (isLocalVariableDeclaration(source))
			return recognizeLocalVariableDeclaration(source);
		if (isClassBodyDeclaration(source))
			return recognizeClassBodyDeclaration(source);
		if (isInterfaceBodyDeclaration(source))
			return recognizeClassBodyDeclaration(source);
		if (isFormalParameter(source))
			return recognizeFormalParameter(source);
		if (isMethodBody(source))
			return recognizeMethodBody(source);
		return recognizeCompilationUnit(source);
	}

	public static final Node recognizeBlock(String source) {
		return new JavaParser(source).Block();
	}

	public static final Node recognizeBlockStatement(String source) {
		return new JavaParser(source).BlockStatement();
	}

	public static final Node recognizeCastExpression(String source) {
		new JavaParser(source).CastExpression();
		return null;
	}

	public static final Node recognizeClassBodyDeclaration(String source) {
		return new JavaParser(source).ClassBodyDeclaration();
	}

	public static final Node recognizeClassOrInterfaceDeclaration(String source) {
		return new JavaParser(source).ClassOrInterfaceDeclaration();
	}

	public static final Node recognizeCompilationUnit(String source) {
		return new JavaParser(source).CompilationUnit();
	}

	public static final Node recognizeContructorDecl(String source) {
		return new JavaParser(source).ConstructorDecl();
	}

	public static final Node recognizeExpression(String source) {
		return new JavaParser(source).Expression();
	}

	public static final Node recognizeFormalParameter(String source) {
		return new JavaParser(source).FormalParameterDecl();
	}

	public static final Node recognizeImport(String source) {
		return new JavaParser(source).ImportDeclaration();
	}

	public static final Node recognizeInterfaceBodyDeclaration(String source) {
		new JavaParser(source).InterfaceBodyDeclaration();
		return null;
	}

	public static final Node recognizeLocalVariableDeclaration(String source) {
		return new JavaParser(source).LocalVariableDeclaration();
	}

	static Node recognizeMethodBody(String source) {
		return new JavaParser(source).MethodBody();
	}

	public static final String recognizePackage(String source) {
		return new JavaParser(source).PackageDeclaration();
	}

	public static final Node recognizePrimary(String source) {
		return new JavaParser(source).Primary();
	}

	public static final Node recognizeStatement(String source) {
		return new JavaParser(source).Statement();
	}

	public static final Node recognizeType(String source) {
		return new JavaParser(source).TypeDeclaration();
	}

	public static final Node recognizeLiteral(String source) {
		return new JavaParser(source).Literal();
	}

	public static Node recognizeUnaryExpression(String source) {
		return new JavaParser(source).UnaryExpression();
	}

	public static Node recognizeMultiplicativeExpression(String source) {
		return new JavaParser(source).MultiplicativeExpression();
	}

	public static Node recognizeAdditiveExpression(String source) {
		return new JavaParser(source).AdditiveExpression();
	}

	public static Node recognizeShiftExpression(String source) {
		return new JavaParser(source).ShiftExpression();
	}

	public static Node recognizeRelationalExpression(String source) {
		return new JavaParser(source).RelationalExpression();
	}

	public static Node recognizeInstanceOfExpression(String source) {
		return new JavaParser(source).InstanceOfExpression();
	}

	public static Node recognizeEqualityExpression(String source) {
		return new JavaParser(source).EqualityExpression();
	}

	public static Node recognizeAndExpression(String source) {
		return new JavaParser(source).AndExpression();
	}

	public static Node recognizeExclusiveOrExpression(String source) {
		return new JavaParser(source).ExclusiveOrExpression();
	}

	public static Node recognizeInclusiveOrExpression(String source) {
		return new JavaParser(source).InclusiveOrExpression();
	}

	public static Node recognizeConditionalAndExpression(String source) {
		return new JavaParser(source).ConditionalAndExpression();
	}

	public static Node recognizeConditionalOrExpression(String source) {
		return new JavaParser(source).ConditionalOrExpression();
	}

	public static Node recognizeConditionalExpression(String source) {
		return new JavaParser(source).ConditionalExpression();
	}
	
	public static Node recognizeMethodDeclaration(String source) {
		return new JavaParser(source).MethodDeclaration(new LinkedList<Modifier>());
	}

	public static Node recognizeMemberDeclaration(String source) {
		return new JavaParser(source).MemberDeclaration(new LinkedList<Modifier>());
	}

	public static Node recognizeMethod(String source) {
		return new JavaParser(source).ClassBodyDeclaration();
	}

	public static Node recognizeVariable(String source) {
		return new JavaParser(source).ClassBodyDeclaration();
	}
}